home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Programmer Disk
/
The Programmer Disk (Microforum).iso
/
xpro
/
extra
/
pro13
/
cc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-28
|
12KB
|
614 lines
/*
cc.C
Version 1.5
Clock Calendar
Copyright (C) 1993, Geoff Friesen B.Sc.
All rights reserved.
Developed with: Borland C++ 3.1
*/
/*
set ti=c:\borlandc\tsr\tsrlib
t cc -hc -x
The BIOS memory location 0040:0084 is set to the number of
screen rows less one. For example, if the screen has been
set to 25 lines then the value 24 would be stored here. A
value of 49 would be stored if 50-line mode were in effect
(on VGA adaptors). This address is used by recent adaptor
BIOSes. Older BIOSes do not use it. Therefore, assume it
to be valid if it returns a 24, 42, or 49. The 42 is used
in EGA 43-line mode.
*/
#if !defined(__TINY__)
#error Tiny Memory Model Expected
#endif
#include "tsrlib.H"
char *title = "\r\n"
"╔═════════════════════════════════════════╗\r\n"
"║ ▒▒▒ ▒▒▒ ║\r\n"
"║ ▒ ▒ ▒ ▒ ║\r\n"
"║ ▒ ▒ ║\r\n"
"║ ▒ ▒ Version 1.5 ║\r\n"
"║ ▒ ▒ ║\r\n"
"║ ▒ ▒ ▒ ▒ ║\r\n"
"║ ▒▒▒ ▒▒▒ ║\r\n"
"║ ║\r\n"
"║ Copyright (C) 1993, Geoff Friesen B.Sc. ║\r\n"
"║ All rights reserved. ║\r\n"
"╚═════════════════════════════════════════╝\r\n"
"$";
int bw [] =
{
WHITE, /* clock */
(LIGHTGRAY << 4) | BLACK, /* calendar back */
WHITE, /* month */
WHITE, /* year */
WHITE /* current day */
};
int color [] =
{
LIGHTGREEN, /* clock */
(CYAN << 4) | BLACK, /* calendar back */
LIGHTMAGENTA, /* month */
LIGHTGREEN, /* year */
YELLOW /* current day */
};
#define NATTR (sizeof(bw)/sizeof(bw [0]))
int attr [NATTR];
char clock_template [] = " 00:00:00 M ";
char *cal_template [] =
{
"╔═════════════════════════════════════════╗",
"║ ║",
"║ ║",
"║ SUN MON TUE WED THU FRI SAT ║",
"╠═════╤═════╤═════╤═════╤═════╤═════╤═════╣",
"║ │ │ │ │ │ │ ║",
"╟─────┼─────┼─────┼─────┼─────┼─────┼─────╢",
"║ │ │ │ │ │ │ ║",
"╟─────┼─────┼─────┼─────┼─────┼─────┼─────╢",
"║ │ │ │ │ │ │ ║",
"╟─────┼─────┼─────┼─────┼─────┼─────┼─────╢",
"║ │ │ │ │ │ │ ║",
"╟─────┼─────┼─────┼─────┼─────┼─────┼─────╢",
"║ │ │ │ │ │ │ ║",
"╟─────┼─────┼─────┼─────┴─────┴─────┴─────╢",
"║ │ │ │ ║",
"╚═════╧═════╧═════╧═══════════════════════╝"
};
#define NCOLS 43
#define NROWS 17
char buffer [(NCOLS+1)*(NROWS+1)*2];
int column = (80-NCOLS)/2;
int row;
int srow = -1; /* suggested row */
int oldyear = 0;
int oldmonth = 0;
int oldday = 0;
char *months [] =
{
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
};
int days [] =
{
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
void draw_cal (struct date *d);
void draw_clock (struct time *t);
int fday (int year, int month);
void write_day (int year, int month, int day);
void write_month (int month);
void write_year (int year);
void mclosectx (char *buffer);
void mhide (void);
int mlbpressed (void);
int mopenctx (char *buffer, int maxsize);
int mrange (int x1, int y1, int x2, int y2);
void mshow (void);
void main (void)
{
struct date d;
struct time t;
static char mbuffer [1000];
int cshape, hidden = 0, i, mexist, nrows, vmode, x, y;
if ((vmode = v_getmode ()) != BW80 && vmode != C80 && vmode != MONO)
return;
nrows = peekb(0x40, 0x84)+1;
if (nrows != 25 && nrows != 43 && nrows != 50)
nrows = 25;
row = (srow == -1 || srow+NROWS > nrows) ? (nrows-NROWS) >> 1 : srow;
for (i = 0; i < NATTR; i++)
attr [i] = (vmode == C80) ? color [i] : bw [i];
cshape = v_getshape ();
v_setshape (0x2000); /* hide cursor */
x = v_wherex ();
y = v_wherey ();
v_screen (SCREEN_SAVE, column, row, NCOLS+1, NROWS+1, buffer);
mexist = mopenctx (mbuffer, 1000);
if (mexist)
mshow ();
while (1)
{
if (mexist && mrange (column, row, column+NCOLS, row+NROWS))
{
mhide ();
hidden = 1;
}
getdate (&d);
draw_cal (&d);
gettime (&t);
draw_clock (&t);
if (mexist && hidden)
{
mshow ();
hidden = 0;
}
if (mexist && mlbpressed ())
break;
if (k_iskey ())
{
(void) k_fetch ();
break;
}
}
if (mexist)
{
mhide ();
mclosectx (mbuffer);
}
v_screen (SCREEN_RESTORE, column, row, NCOLS+1, NROWS+1, buffer);
v_gotoxy (x, y);
v_setshape (cshape);
oldyear = oldmonth = oldday = 0;
}
void draw_cal (struct date *d)
{
int i;
if (d->da_year == oldyear && d->da_mon == oldmonth
&& d->da_day == oldday)
return;
v_setattr (attr [1]);
for (i = 0; i < NROWS; i++)
{
v_gotoxy (column, row+i);
v_cputs (cal_template [i]);
}
v_shadow (column, row, NCOLS, NROWS);
write_year (d->da_year);
write_month (d->da_mon);
write_day (d->da_year, d->da_mon, d->da_day);
oldyear = d->da_year;
oldmonth = d->da_mon;
oldday = d->da_day;
}
void draw_clock (struct time *t)
{
clock_template [10] = (t->ti_hour < 12) ? 'A' : 'P';
if (!t->ti_hour)
t->ti_hour = 12;
else
if (t->ti_hour > 12)
t->ti_hour -=12;
clock_template [1] = t->ti_hour / 10 + ((t->ti_hour < 10) ? ' ' : '0');
clock_template [2] = t->ti_hour % 10 + '0';
clock_template [4] = t->ti_min / 10 + '0';
clock_template [5] = t->ti_min % 10 + '0';
clock_template [7] = t->ti_sec / 10 + '0';
clock_template [8] = t->ti_sec % 10 + '0';
v_setattr (attr [0]);
v_gotoxy (column+NCOLS-19, row+NROWS-2);
v_cputs (clock_template);
}
int fday (int year, int month)
{
int i, d = 0;
for (i = 1583; i < year; i++)
{
if (isleap (i))
d += 366;
else
d += 365;
d %= 7;
}
for (i = 1; i < month; i++)
{
d += days [i-1];
if (i == 2 && isleap (year))
d++;
d %= 7;
}
if (!d)
d = 7;
return (d-1);
}
void write_day (int year, int month, int day)
{
int c, d, nd, r;
char buffer [3];
c = fday (year, month) * 6 + 3;
r = 5;
nd = days [month-1];
if (month == 2 && isleap (year))
nd++;
v_setattr (attr [1]);
buffer [2] = '\0';
for (d = 1; d <= nd; d++)
{
buffer [0] = d / 10 + ((d < 10) ? ' ' : '0');
buffer [1] = d % 10 + '0';
v_gotoxy (column+c, row+r);
if (d == day)
{
v_setattr (attr [4]);
v_cputs (buffer);
v_setattr (attr [1]);
}
else
v_cputs (buffer);
if ((c += 6) > 39)
{
c = 3;
r += 2;
}
}
}
void write_month (int month)
{
v_gotoxy (column+((NCOLS-strlen (months [--month])) >> 1), row+1);
v_setattr (attr [2]);
v_cputs (months [month]);
}
void write_year (int year)
{
char buffer [5];
(void) _itoa (year, buffer);
v_setattr (attr [3]);
v_gotoxy (column+2, row+1);
v_cputs (buffer);
v_gotoxy (column+NCOLS-6, row+1);
v_cputs (buffer);
}
/*
mclosectx
Close the mouse context. Restore the mouse driver to its
original settings.
*/
void mclosectx (char *buffer)
{
_ES = FP_SEG(buffer);
_DX = FP_OFF(buffer);
_AX = 0x17;
geninterrupt(0x33);
}
/*
mhide
Hide the mouse cursor.
*/
void mhide (void)
{
_AX = 2;
geninterrupt(0x33);
}
/*
mlbpressed
Return the pressed/released status of the leftmost mouse button.
A nonzero return value indicates that the button is pressed.
*/
int mlbpressed (void)
{
_AX = 3;
geninterrupt(0x33);
return (_BX & 1);
}
/*
mopenctx
Open the mouse context. The current driver settings are saved
to the buffer argument. The mouse driver is then reset. Zero
is returned if there is no installed driver or the buffer size
required to hold the driver settings exceeds the maximum size
passed to this function.
*/
int mopenctx (char *buffer, int maxsize)
{
_AX = 0x15;
geninterrupt(0x33);
if (!_BX || _BX > maxsize)
return 0;
_ES = FP_SEG(buffer);
_DX = FP_OFF(buffer);
_AX = 0x16;
geninterrupt(0x33);
_AX = 0;
geninterrupt(0x33);
return (!_AX) ? 0 : 1;
}
/*
mrange
Determine if mouse cursor lies within a specific rectangle.
Return nonzero if it does.
*/
int mrange (int x1, int y1, int x2, int y2)
{
unsigned x, y;
_AX = 3;
geninterrupt(0x33);
x = _CX;
y = _DX;
x >>= 3; /* Convert pixel coordinates to character coordinates. */
y >>= 3;
x++;
y++; /* Make coordinates relative to (1, 1). */
return (x >= x1 && x <= x2 && y >= y1 && y <= y2);
}
/*
mshow
Show the mouse cursor.
*/
void mshow (void)
{
_AX = 1;
geninterrupt(0x33);
}
#ifndef INCL_GETDATE
#include "getdate.C"
#endif
#ifndef INCL_GETTIME
#include "gettime.C"
#endif
#ifndef INCL_ISDIGIT
#include "isdigit.C"
#endif
#ifndef INCL_ISLEAP
#include "isleap.C"
#endif
#ifndef INCL_ITOA
#include "itoa.C"
#endif
#ifndef INCL_KFETCH
#include "kfetch.C"
#endif
#ifndef INCL_KISKEY
#include "kiskey.C"
#endif
#ifndef INCL_VCPUTS
#include "vcputs.C"
#endif
#ifndef INCL_VGETMODE
#include "vgetmode.C"
#endif
#ifndef INCL_VGETSHAPE
#include "vgetshap.C"
#endif
#ifndef INCL_VGOTOXY
#include "vgotoxy.C"
#endif
#ifndef INCL_VSCROLL
#include "vscroll.C"
#endif
#ifndef INCL_VSETATTR
#include "vsetattr.C"
#endif
#ifndef INCL_VSETSHAPE
#include "vsetshap.C"
#endif
#ifndef INCL_VSHADOW
#include "vshadow.C"
#endif
#ifndef INCL_VWHEREX
#include "vwherex.C"
#endif
#ifndef INCL_VWHEREY
#include "vwherey.C"
#endif
int xparse (int option)
{
int accum, digit;
if (option == 'R') /* RESET OPTION */
{
setrseg ();
column = (80-NCOLS)/2;
srow = -1;
setcseg ();
return 0;
}
if (option == 'X') /* COLUMN OPTION */
{
if (!isdigit ((digit = parse ())))
{
_AH = 9;
_DX = FP_OFF("cc: digit expected after 'X'\r\n$");
geninterrupt(0x21);
return -1;
}
accum = digit-'0';
if (!isdigit ((digit = parse ())))
unparse ();
else
{
accum *= 10;
accum += (digit-'0');
}
if (accum < 1 || accum > (80-NCOLS))
{
_AH = 9;
_DX = FP_OFF("cc: column out of range ...\r\n$");
geninterrupt(0x21);
return -1;
}
setrseg ();
column = accum;
setcseg ();
return 0;
}
if (option == 'Y') /* ROW OPTION */
{
if (!isdigit ((digit = parse ())))
{
_AH = 9;
_DX = FP_OFF("cc: digit expected after 'Y'\r\n$");
geninterrupt(0x21);
return -1;
}
accum = digit-'0';
if (!isdigit ((digit = parse ())))
unparse ();
else
{
accum *= 10;
accum += (digit-'0');
}
if (accum < 1 || accum > (50-NROWS))
{
_AH = 9;
_DX = FP_OFF("cc: row out of range ...\r\n$");
geninterrupt(0x21);
return -1;
}
setrseg ();
srow = accum;
setcseg ();
return 0;
}
return -1;
}